Stocks

Reagents, species, organisms, and the Stock types that combine them. See the Reagents & Species and Stocks manual chapters. Composition and acid/base chemistry are on the Solution Chemistry page.

CHESSCore.StockComponent — Type
abstract type StockComponent end

Common supertype for anything a Stock can contain and track a quantity of – Reagent (chemical substances: Solid/Liquid/Gas) and Organism. Exists purely as a dispatch/gathering anchor – e.g. so Pourfecto's planning code can enumerate everything in a Stock uniformly – not as a shared-behavior contract: StockComponent has no fields or methods of its own, and Reagent's chemistry-specific machinery (molecular weight, density, dissolution, PubChem-backed persistence) is not inherited by Organism, nor is anything organism-specific inherited by Reagent.

source
CHESSCore._element_symbols — Constant
_element_symbols

The set of element symbols accepted in formula strings: the 118 named elements of PeriodicTable.jl. (PeriodicTable.jl also carries a placeholder entry for element 119, which is excluded.)

source
CHESSCore.opaque — Constant
opaque

Marker for intentionally undeterminable atomic content: pass it where a formula string is expected, as in Species("yeast extract",0,CHESSCore.opaque), or write opaque in the formula position of @species and @reagent. Call it with a molar mass, opaque(1415.6u"g/mol"), for content that has no formula but a known average molecular weight (a mixture sold as a salt, or a solution whose stated purity makes its effective molecular weight differ from the compound's). Without a molar mass the species has no molecular weight and no moles are tracked for it.

source
CHESSCore.OpaqueFormula — Type
OpaqueFormula

The type of CHESSCore.opaque, the marker for a species whose atomic content is intentionally not described (an undefined mixture such as yeast extract). It is distinct from a missing formula, which means the formula has not been registered yet. It may carry an average molecular weight, given by calling the marker: opaque(1415.6u"g/mol").

source
CHESSCore.formula_mass — Method
formula_mass(counts::AbstractDict{Symbol,<:Integer}) -> Unitful.MolarMass
formula_mass(str::AbstractString)

Return the molar mass (in g/mol) of a formula given as element counts or as a formula string (see parse_formula), summed from the atomic masses in PeriodicTable.jl. The atomic mass in daltons is taken as the molar mass in g/mol.

source
CHESSCore.formula_string — Method
formula_string(counts::AbstractDict{Symbol,<:Integer}) -> String

Write element counts as a canonical formula string in Hill order: carbon first and hydrogen second when carbon is present, then the remaining elements alphabetically (all elements alphabetically when there is no carbon). A count of one is omitted. parse_formula reads the result back to the same counts, so equal formulas always give the same string.

source
CHESSCore.parse_formula — Method
parse_formula(str::AbstractString) -> Dict{Symbol,Int}

Parse an elemental formula string into a dictionary from element symbol to atom count.

Supported syntax:

  • element symbols (one capital letter, optionally one lowercase letter) with an optional integer count: C6H12O6, NaCl. CO is carbon monoxide and Co is cobalt.
  • groups in parentheses or square brackets with an optional multiplier: Fe(OH)3, K4[Fe(CN)6].
  • hydrate parts joined by a middle dot · or an ASCII period, each with an optional leading integer coefficient: FeSO4·7H2O, FeSO4.7H2O, 2NaOH·H2O.

Elements can appear in any order. A repeated element is summed. Charge is not part of the formula string. Whitespace, fractional coefficients, isotopes ([13C], D, T) and unknown symbols raise an ArgumentError.

source
CHESSCore.H⁺ — Constant
const H⁺

The canonical hydrogen ion (proton), used by pH/total_concentration. Any custom dissolution rule representing proton transfer (e.g. a strong base contributing a negative count, so it nets against acids in the same sum) should reuse this exact value rather than defining its own separate "H+" Species, so contributions net correctly.

source
CHESSCore.dissolutions — Constant
const dissolutions

Registry mapping a specific Reagent value (e.g. the NaCl returned by @reagent) to its Dissolution. A per-value registry, not per-type dispatch, because individual reagents are themselves named values of a small set of types (Solid/Liquid/Gas) — dispatch on typeof(reagent) cannot distinguish e.g. HCl from NaOH (both Solid). Prefer set_dissolution! over mutating this directly.

source
CHESSCore.Dissolution — Type
struct Dissolution

Describes the stoichiometric products of a Reagent breaking down into Speciess — e.g. Dissolution(Dict(Na⁺=>1, Cl⁻=>1)) for NaCl, or Dissolution(Dict(glucose_chem=>1)) for a non-dissociating reagent (its own identity). Coefficients must be non-negative – represent an acid/base's hydroxide contribution via OH⁻, not a negative H⁺ count (see net_hydrogen_ion_concentration) – since molecular_weight sums a reagent's registered products directly.

+ and * build a Dissolution from Species values: spc"Na+" + spc"Cl-", or spc"Mg2+" + 2*spc"Cl-". A reagent is defined from one by @reagent or registered with set_dissolution!.

source
CHESSCore.Liquid — Type
struct Liquid <: Reagent

Liquids are Reagent subtypes that exist in liquid phase at STP. We typically express liquid quantities in terms of a volume.

source
CHESSCore.Reagent — Type
abstract type Reagent end

Represents a physical material: a substance you can weigh out or pipette and store. Reagents identify the materials in the lab's mixtures and solutions, tracked in Stock's SolidDict/LiquidDict.

All Reagent subtypes have four fields utilized by CHESSCore:

  1. name: the name by which the reagent will be referred to
  2. molecular_weight: the reagent's stored molecular weight. For a reagent defined by a formula or a Dissolution, this is the weight derived from it when the reagent was defined, and molecular_weight re-derives it from the registered dissolution whenever one exists. If the weight is unknown, missing.
  3. density: the reagent's density at STP, if known, is used by CHESSCore to facilitate conversions between mass and volume quantities of the reagent. If density is unknown or undefined, it is assigned a value of missing
  4. pubchemid: the reagent's integer PubChem ID, which identifies the reagent's compound in the PubChem database.

See also: Species for what a reagent breaks into once dissolved, @reagent for defining one, and StockComponent for the common dispatch/gathering ancestor Reagent shares with Organism.

source
CHESSCore.Solid — Type
struct Solid <: Reagent

Solids are Reagent subtypes that exist in solid phase at STP. We typically express solid quantities in terms of a mass or moles.

source
CHESSCore.Species — Type
struct Species

Represents a species — what a Reagent behaves as once it's part of a reactive system (e.g. Na⁺, Cl⁻ from dissolved NaCl; or, trivially, glucose's own identity for a non-dissociating reagent). Species values are never added directly to a Stock — they exist purely as the output vocabulary of dissolution (per-Reagent) and Composition (per-Stock), without changing how Stock stores its (undissociated) Reagent components.

A species carries a name, an integer charge (0 for neutral species), and one of three descriptions of its atomic content:

  • an elemental formula string such as "C6H12O6" (see CHESSCore.parse_formula), from which molecular_weight is derived using atomic masses;
  • a stored molecular weight (or missing), for a species whose formula is not registered yet; or
  • CHESSCore.opaque, for a species whose atomic content is intentionally not described.
julia> Species("glucose",0,"C6H12O6")

julia> Species("mystery ion",1,missing)

Unlike Reagent, Species has real value-based equality/hash (not Julia's identity-based default) because dissolutions and the identity-default fallback (see dissolution) routinely construct Species values on the fly, and those must compare equal to independently-constructed-but- identical values for Dict lookups (e.g. Composition/total_concentration) to work correctly. Two species are equal when their name, charge, and formula are equal (and, for species without a formula, their stored molecular weights).

source
Base.convert — Method
convert(desired_unit, current_unit, ingredient::Union{Reagent,Species})

Unitful.uconvert wrapper to convert a quantity from a molar quantity to a mass quantity and vice-versa, for either a Reagent or a Species.

convert accesses the stored molecular_weight to make the conversion using the Unitful.uconvert function.

source
CHESSCore._charge_symbol_candidates — Method
_charge_symbol_candidates(sym::Symbol)

Generate plausible canonical-superscript-charge spellings of sym's plain-ASCII form (e.g. :Na+ -> [:Na⁺]; :Ca2+ -> [:Ca⁺, :Ca²⁺]; Symbol("SO4 2-") -> [:SO4⁻, :SO4²⁻]), superscripting a trailing ASCII +/- and, progressively, 0/1/2 trailing digits before it. Internal whitespace is stripped first (CHESSCore's registered names never contain spaces, even though some display name strings do, e.g. "SO4 2-"). Returns Symbol[] if sym doesn't end in an ASCII +/- at all. Candidates are tried in order (fewest digits superscripted first) by lookup_named_value, which only accepts one that resolves to an actual registered binding – this is what resolves the ambiguity between a charge-magnitude digit (Ca2+ -> Ca²⁺) and a formula digit that happens to precede the sign (H2PO4- -> H2PO4⁻, not H2PO⁴⁻).

source
CHESSCore.dissolution — Method
dissolution(x::Reagent)

Return the Dissolution describing how x breaks down into Speciess when dissolved. Every Reagent has a dissolution — a non-electrolyte's default (for anything not registered via set_dissolution!) is simply its own identity Species (Dissolution(Dict(Species(name(x),0,molecular_weight(x))=>1))), not "no dissolution."

source
CHESSCore.formula — Method
formula(x::Species)

Return the elemental formula of a Species as a dictionary from element symbol to atom count, missing if no formula is registered, or CHESSCore.opaque if the atomic content is intentionally not described.

source
CHESSCore.lookup_named_value — Method
lookup_named_value(labmods, ex, check::Function)

Shared lookup machinery behind @spc_str, @rgt_str, @org_str, and @loc_str: resolve a bare symbol (or an arithmetic expression/tuple of symbols) against a list of modules, using check(value) to decide whether a candidate binding is of the desired kind. Falls back to searching all globally registered labmodules for a helpful "did you mean" suggestion (Levenshtein distance) when nothing matches.

source
CHESSCore.molecular_weight — Method
molecular_weight(x::Reagent)

The molecular weight of a reagent: derived from its registered dissolution (dissolutions) when one exists (the sum of each product Species's molecular weight times its coefficient), falling back to the reagent's stored value otherwise. Deriving from the dissolution is safe because every registered Dissolution is required to be non-negative, real stoichiometry (see its constructor).

source
CHESSCore.molecular_weight — Method
molecular_weight(x::Species)

Return the molecular weight of a Species: derived from its elemental formula using atomic masses when it has one, otherwise its stored molecular weight (missing if none). An opaque species has the average molecular weight given to opaque, or missing if none was given.

source
CHESSCore.reagentparse — Method
reagentparse(str; reagent_context=CHESSCore)

Non-macro equivalent of @rgt_str — parses str as a Reagent expression, looked up against reagent_context (a Module or list of Modules).

source
CHESSCore.set_dissolution! — Method
set_dissolution!(r::Reagent,rule::Dissolution)

Register that r breaks down into ions/chemicals according to rule when dissolved — see dissolution. A reagent is neutral, so the charges of the products, weighted by their coefficients, must sum to zero; otherwise an ArgumentError is thrown.

source
CHESSCore.speciesparse — Method
speciesparse(str; species_context=CHESSCore)

Non-macro equivalent of @spc_str — parses str as a Species expression, looked up against species_context (a Module or list of Modules).

source
CHESSCore.symbol — Method
symbol(x; context=vcat([CHESSCore],CHESSCore.labmodules))

Return the Symbol that x is bound to somewhere in context (a Module or list of Modules, default: CHESSCore plus every module registered via CHESSCore.register_lab) — the reverse of looking a value up via @spc_str/@rgt_str/@org_str. This is the reliable way to get back the identifier you'd use to reference x in code; name is a separate, display-oriented string not guaranteed to correspond to any actual binding (e.g. H⁺ is bound under :H⁺, but name(H⁺) == "H+"). Throws ArgumentError if no matching binding is found (common for ephemeral values, e.g. Species values built on the fly by dissolution's default branch, which were never bound to a constant at all).

source
CHESSCore.@reagent — Macro
@reagent labname name type chemistry density pubchemid

Define a new reagent (a physical Solid/Liquid/Gas) and import it into the workspace under labname. The name argument is the display name for the reagent, which can include a larger set of characters and formatting than the labname. For a given reagent, its type parameter should be the phase in which it exists at STP: Solid, Liquid, or Gas.

The chemistry argument says what the reagent is made of, and is one of:

  • an elemental formula string such as "C6H12O6": the reagent dissolves to a single neutral species of the same name with that formula, and its molecular weight is derived from the formula;
  • a Dissolution built from species, such as spc"Fe3+" + 3*spc"Cl-": the reagent breaks into those species, and its molecular weight is derived from them;
  • a molar mass such as 180.16u"g/mol", for a reagent whose formula is not registered yet: its identity species has no formula and keeps this stored molecular weight;
  • missing, when nothing is known about its chemistry; or
  • opaque, for an undefined mixture such as yeast extract whose atomic content is intentionally not described, or opaque(1415.6u"g/mol") for one with a known average molar mass.

The reagent's dissolution is registered with set_dissolution! (discoverable in dissolutions), and is kept with the defining module so it survives precompilation.

Examples:

julia> using Unitful

julia> @reagent glucose "D-glucose" Solid "C6H12O6" 1.2u"g/mL" 5793
D-glucose

julia> @reagent iron_chloride "iron chloride" Solid (spc"Fe3+" + 3*spc"Cl-") 2.8u"g/mL" 24380
iron chloride

julia> @reagent water "water" Liquid 18.015u"g/mol" 1.00u"g/mL" 962
water

julia> @reagent yeast_extract "yeast extract" Solid opaque 1.0u"g/mL" missing
yeast extract

julia> @reagent bleomycin "bleomycin" Solid opaque(1415.6u"g/mol") missing 5360373
bleomycin

julia> molecular_weight(water)
18.015 g mol⁻¹

Reagents can also be defined manually with type constructors.

Example:

julia> water=Liquid("water",18.015u"g/mol",1.00u"g/mL",962)
water

See also: Solid, Liquid, Gas, Dissolution, @species

source
CHESSCore.@species — Macro
@species labname name charge formula

Define a new Species value (e.g. an ion like Na⁺, or a standalone neutral species) and import it into the workspace under labname. charge is 0 for neutral species. formula is an elemental formula string such as "C6H12O6"; the molecular weight is derived from it. A molar mass (or missing) may be given instead of a formula for a species whose formula is not registered yet, and opaque (or opaque(mass) with an average molar mass) for a species whose atomic content is intentionally not described.

Example:

julia> @species Na⁺ "Na+" 1 "Na"
Na+

julia> @species glucose_species "D-glucose" 0 "C6H12O6"
D-glucose

See also: @reagent for defining physical-form Reagents instead, @spc_str, Dissolution.

source
CHESSCore.Organism — Type
struct Organism

A unique species (and strain). organisms can be combined with Stock objects to create Culture objects

Organsim objects have three properties:

  1. genus: The strain's taxonomic genus
  2. species: The Strains taxonomic species
  3. strain: The strain's identifier

See also: StockComponent for the common dispatch/gathering ancestor Organism shares with Reagent.

source
CHESSCore.@org_str — Macro
@org_str(organism)

String macro to recall an Organism registered with @organism by name, for example org"SMU_UA159". It searches CHESSCore and any registered lab module loaded where the macro is called, and throws an error if no organism by that name exists. This is the organism counterpart of @rgt_str.

See also: orgparse for the non-macro form.

source
CHESSCore.@organism — Macro
macro organism(labsymb, genus, species, strain)

A macro to quickly define a new Organism object and import it into the workspace under labname.

source
CHESSCore.Biomass — Type
const Biomass

Quantity type for tracking how much of an Organism is present in a Culture. Dimensionally OD * Volume (reusing JensenLabUnits.AbsorbanceVolume), so biomass/volume recovers an OD reading by construction. Biomass is an absolute, conserved quantity – like Unitful.Mass for a Solid – not a value derived from a Culture's current liquid volume.

source
CHESSCore.stock_recipes — Constant
const stock_recipes

Registry mapping a name to a Stock recipe registered via @stock. Unlike a bare const binding of a Stock value, only recipes registered this way are reachable via @stock_str – an intermediate Stock (e.g. a concentrated stock solution used only as an ingredient in a larger recipe) never accidentally becomes discoverable.

source
CHESSCore.Culture — Type
struct Culture <: Stock

Culture objects are stocks that contain at least one Organism, each carrying a Biomass quantity. Cultures may contain any number of Solid or Liquid components, and may have zero liquid volume (biomass is an absolute quantity, not derived from the Culture's current volume).

source
CHESSCore.Empty — Type
struct Empty <:Stock end

Singleton type that represents an empty Stock object.

source
CHESSCore.Mixture — Type
struct Mixture <:Stock

Mixture objects are stocks that only contain Solid components. Mixtures must contain at least one solid. (Otherwise, they would be Empty stocks.)

source
CHESSCore.Solution — Type
struct Solution <:Stock

Solution objects are stocks that only contain at least one Liquid component but no organisms. Solutions may contain any number of Solid components

source
CHESSCore.Stock — Type
abstract type Stock end

Stock objects represent combinations of organisms and chemicals quantities.

source
CHESSCore.Stock — Method
function Stock(organisms,solids,liquids)

a generic stock constructor that returns the appropriate stock subtype.

source
Base.:* — Method
*(q::Unitful.Quantity,stock::Empty)

Any quantity of an Empty stock is still Empty – unlike the general Stock method above, this never needs quantity(stock) (which is missing for Empty), so it can't hit the missing division/conversion that method would otherwise perform.

source
Base.:* — Method
*(q::Unitful.Quantity,stock::Stock)

Overload the * operator to divide a stock by a quantity. Returns a new stock scaled to have a total quantity q

source
Base.:* — Method
*(num::Real,stock::Stock)

Overload the * operator to multiply the chemicals and organisms of a Stock by a scalar. Returns a new Stock with all chemical/biomass quantities scaled by a factor of num.

source
Base.:* — Method
*(quantity::Biomass,organism::Organism)

Overload the * operator to construct a Culture from a Biomass quantity of an Organism. This is the standard way to write an inoculum, e.g. 5u"OD*mL" * ecoli.

source
Base.:* — Method
*(quantity::Unitful.Volume,chemical::Liquid)

Overload the * operator to construct a Solution from a volume of a liquid.

source
Base.:* — Method
*(quantity::Unitful.Mass,chemical::Solid)

Overload the * operator to construct a Mixture from a mass of a solid.

source
Base.:* — Method
*(quantity::Unitful.Amount,chemical::Solid)

Overload the * operator to construct a Mixture from a molar quantity of a solid.

source
Base.:/ — Method
/(stock::Stock,num::Real)

Overload the / operator to divide a Stock by a scalar. Returns a new Stock with all chemical quantities scaled by a factor of 1/num.

source
CHESSCore.liquids — Method
liquids(::Stock)

access the liquids Dict for a Stock. If no liquids are present, return LiquidDict()

source
CHESSCore.organisms — Method
organisms(::Stock)

return the organisms property of a Stock (an OrganismDict, a Dict mapping each present Organism to its Biomass). If no organisms are present, return OrganismDict().

source
CHESSCore.reagents — Method
reagents(x::Union{SolidDict,LiquidDict,OrganismDict})

a wrapper for collect(keys(x)) that returns an array of the chemical/organism keys.

source
CHESSCore.solids — Method
solids(::Stock)

access the solids Dict for a Stock. If no solids are present, return SolidDict()

source
CHESSCore.volume_estimate — Method
volume_estimate(s::Stock)

Return the estimated volume of a Stock s

  • Empty returns a value of 0u"mL"
  • Mixture approximates the volume based on the density of each reagent. Reagents with a missing density are excluded from the sum (rather than propagating missing and zeroing out the whole estimate) – the result is therefore a lower bound, and a warning is emitted when this happens.
  • Solution returns quantity(s)
source
CHESSCore.@stock — Macro
@stock name expr

Register expr (a Stock-producing expression) under name, both as a const binding and in the stock_recipes registry – mirrors @location_kind. This is what makes a recipe reachable via @stock_str; a plain const binding of a Stock is not.

Example:

julia> @stock saline_recipe 1u"mL" * water + 5u"g" * NaCl
saline_recipe

julia> stock"saline_recipe"
source
CHESSCore._pretty_quantity — Method
_pretty_quantity(q; sigdigits=3) -> String

Display string for q with sigdigits significant figures. Volumes, masses, molar amounts, biomass, mass-per-volume and molar concentrations are rescaled to the metric prefix that puts the number in [1, 1000) – 2.00 mg rather than 0.0 g, 198 μL rather than 0.2 mL – clamped to the smallest and largest prefixes CHESS displays. Any other unit (percent, OD, ...) keeps its unit. Zero keeps q's own unit, and missing displays as "missing".

source
CHESSCore._reagent_table — Method
_reagent_table(dict::Union{SolidDict,LiquidDict,OrganismDict}, total; digits=2)

Shared logic behind both show(::MIME"text/plain",::Stock) and reagent_display: sort dict's reagents by name and compute each one's amount and concentration relative to total (the stock's overall quantity/volume_estimate), via _relative_amount. Returns (sorted_reagents, amounts, concentrations), all empty if dict is empty. For an OrganismDict, "concentration" comes out as Biomass/total – i.e. the current, on-demand-derived OD – since Biomass's dimension differs from total's (see _relative_amount). digits=nothing leaves the values unrounded, for display formatting by _pretty_quantity.

source
CHESSCore._relative_amount — Method
_relative_amount(amt, total; digits=nothing)

Shared dimension-matching rule behind _reagent_table and concentration (src/interop/stock_utils.jl): if amt shares total's physical dimension, express it as a percentage of total; otherwise express it as an amount-per-unit-of-total (e.g. g/mL). Optional digits rounds the result.

source
CHESSCore.reagent_display — Method
reagent_display(s::Stock; digits=2)

Return (solids, liquids, organisms) for s: all three are Dict{String,Dict{String,Tuple}} keyed by name, each holding "Amount"/"Concentration" (value, unit) tuples computed by _reagent_table (the same logic show(::MIME"text/plain",::Stock) uses). For organisms, "Amount" is each organism's Biomass and "Concentration" is its current, on-demand OD.

source
CHESSCore.JensenLabUnits — Module
JensenLabUnits

Unitful units used by CHESS that are not in Unitful itself: optical density OD (dimension absorbance), relative fluorescence RFU, an unspecified concentration X (as in "2X media"), and relative centrifugal force xg. It also defines the derived dimension AbsorbanceVolume (absorbance times volume), which CHESSCore.Biomass uses. The units are registered with Unitful when the module loads, so u"OD" and friends work after using CHESSCore.

source