Skip to content

Databases

ChemistryLab.datapath Method
julia
datapath(parts::AbstractString...) -> String

Absolute path to a file shipped in ChemistryLab's data/ directory. Called without argument, returns the directory itself.

This is the recommended way to name a bundled database, because it does not depend on the working directory: a script written this way runs identically from the package root, from an editor whose REPL started elsewhere, and inside a documentation build.

Examples

julia
substances = build_species(datapath("cemdata18-thermofun.json"))
ss_phases  = build_solid_solutions(datapath("solid_solutions.toml"), dict)
readdir(datapath())                       # every bundled data file
datapath("experimental", "README.md")     # subdirectories work too

See also read_thermofun_database, build_species.

ChemistryLab.display_data_path Method
julia
display_data_path(path::AbstractString) -> String

Short, machine-independent label for path, meant for the banner a reader sees rather than for opening a file.

A file inside the package is shown relative to the package root (data/cemdata18-thermofun.json); anything else is shown unchanged. This matters because these banners are captured verbatim into the documentation: printing the absolute path would bake the build machine's directories (/home/runner/work/...) into every page that loads a database.

ChemistryLab.resolve_data_path Method
julia
resolve_data_path(path::AbstractString) -> String

Resolve path to an existing file, trying in order:

  1. path as given — relative to the working directory, or absolute;

  2. datapath(path) — the same relative path under the bundled data/;

  3. datapath(basename(path)) — a bundled data file of that name, whatever directory prefix the caller wrote;

  4. joinpath(pkgdir(ChemistryLab), path) — relative to the package root.

The working directory comes first, so a call that already resolves keeps resolving to exactly the same file: the fallbacks can only turn a failure into a success, never change an existing answer. And steps 2–3 can only succeed for a name that is one of the bundled data files, so a mistyped path to a file of one's own still fails loudly instead of silently loading something else.

Throws ArgumentError listing the bundled files when nothing matches.

ChemistryLab.HKF_SI_CONVERSIONS Constant
julia
HKF_SI_CONVERSIONS

Hardcoded conversion factors from SUPCRT (cal, bar) to SI (J, Pa) for eos_hkf_coeffs. The JSON unit metadata for a3 and a4 is incorrect (missing /bar), hence this explicit table.

SymbolSUPCRT unitSI unitFactor
a1cal/(mol·bar)J/(mol·Pa)4.184e-5
a2cal/molJ/mol4.184
a3(cal·K)/(mol·bar)(J·K)/(mol·Pa)4.184e-5
a4cal·K/molJ·K/mol4.184
c1cal/(mol·K)J/(mol·K)4.184
c2cal·K/molJ·K/mol4.184
wrefcal/molJ/mol4.184
ChemistryLab.build_reactions Function
julia
build_reactions(df_reactions::AbstractDataFrame, dict_species=Dict(), list_symbols=nothing; verbose=false) -> Vector{Reaction}

Build Reaction objects from a reaction DataFrame.

Arguments

  • df_reactions: DataFrame containing reaction data.

  • species_list: vector of existing Species objects to use in reactions.

  • list_symbols: optional list of reaction symbols to filter (default: nothing, process all).

  • verbose: if true, print details during processing (default: false).

Returns

  • Vector of Reaction objects.
ChemistryLab.build_solid_solutions Method
julia
build_solid_solutions(toml_file, dict_species; skip_missing=true) -> Vector{SolidSolutionPhase}

Load solid solution phase definitions from a TOML file and assemble SolidSolutionPhase objects from an existing species dictionary.

Each end-member species is automatically requalified to SC_SSENDMEMBER via with_class, regardless of the class stored in the database.

Arguments

  • toml_file: path to a TOML file with [[solid_solution]] entries (see data/solid_solutions.toml for the format).

  • dict_species: Dict{String, <:AbstractSpecies} mapping symbol → species (typically built from Dict(symbol(s) => s for s in build_species(...))).

  • skip_missing: if true (default), silently skip phases whose end-members are not all present in dict_species; if false, throw an error.

TOML format

toml
[[solid_solution]]
name        = "CSHQ"
end_members = ["CSHQ-TobD", "CSHQ-TobH", "CSHQ-JenH", "CSHQ-JenD", "KSiOH", "NaSiOH"]
model       = "ideal"          # or "redlich_kister"
# For redlich_kister only:
a0          = 3000.0           # J/mol
a1          = 500.0            # J/mol
a2          = 0.0              # J/mol

Example

julia
substances = build_species(datapath("cemdata18-thermofun.json"))
dict       = Dict(symbol(s) => s for s in substances)
ss_phases  = build_solid_solutions(datapath("solid_solutions.toml"), dict)
cs = ChemicalSystem(species, CEMDATA_PRIMARIES; solid_solutions = ss_phases)
ChemistryLab.build_species Function
julia
build_species(df_substances::AbstractDataFrame, list_symbols=nothing; verbose=false) -> Vector{Species}

Build Species objects from a substance DataFrame.

Arguments

  • df_substances: DataFrame containing substance data.

  • list_symbols: optional list of symbols to filter (default: nothing, process all).

  • verbose: if true, print details during processing (default: false).

Returns

  • Vector of Species.
ChemistryLab.complete_reaction_with_thermo_model! Method
julia
complete_reaction_with_thermo_model!(reaction, row; verbose=false)

Populate thermodynamic reference values and build thermodynamic functions on reaction from a ThermoFun reaction DataFrame row. Mutates reaction.properties in place.

ChemistryLab.complete_species_with_thermo_model! Method
julia
complete_species_with_thermo_model!(species, row; verbose=false)

Populate thermodynamic reference values and build thermodynamic functions on species from a ThermoFun substance DataFrame row. Mutates species.properties in place.

ChemistryLab.extract_unit Function
julia
extract_unit(v, default_unit=u"1") -> AbstractQuantity

Try to parse the string v as a unit via uparse. Returns default_unit if parsing fails.

ChemistryLab.extract_value Method
julia
extract_value(row, field; verbose=false, default_unit=u"1", with_units=true) -> Union{AbstractQuantity, Number, Missing}

Extract a scalar value (optionally with units) from a nested ThermoFun DataFrame row. Returns missing when the field is absent, missing, or cannot be parsed.

ChemistryLab.get_compatible_species Method
julia
get_compatible_species(df_substances::AbstractDataFrame, species_list; aggregate_states=[AS_AQUEOUS], exclude_species=[], union=false) -> DataFrame

Find species in the database compatible with a given list of species (sharing atoms).

Arguments

  • df_substances: substance DataFrame.

  • species_list: list of target species symbols.

  • aggregate_states: filter for specific aggregate states (default: [AS_AQUEOUS]).

  • exclude_species: list of species symbols to exclude.

  • union: if true, includes the original species_list in the result (default: false).

Returns

  • DataFrame of compatible substances.
ChemistryLab.read_thermofun_database Method
julia
read_thermofun_database(filename::AbstractString) -> (DataFrame, DataFrame, DataFrame)

Read a ThermoFun database from a JSON file.

Arguments

  • filename: path to the JSON database file.

Returns

  • df_elements: DataFrame of chemical elements.

  • df_substances: DataFrame of chemical substances (species).

  • df_reactions: DataFrame of chemical reactions.

ChemistryLab.extract_primary_species Method
julia
extract_primary_species(file_path::AbstractString) -> DataFrame

Extract primary aqueous species from a PHREEQC database file.

Arguments

  • file_path: path to PHREEQC .dat file.

Returns

  • DataFrame with columns: species, symbol, formula, aggregate_state, atoms, charge, gamma.

Parses the SOLUTION_SPECIES section to extract master species and their properties. The "Zz" charge placeholder is handled specially. Gamma coefficients for activity models are extracted from "-gamma" lines.

ChemistryLab.parse_float_array Method
julia
parse_float_array(line::AbstractString) -> Vector{Float64}

Parse a line containing space-separated floats, skipping the first token and any comments.

Arguments

  • line: input string with format "keyword value1 value2 ...".

Returns

  • Vector of successfully parsed Float64 values.

Examples

julia
julia> parse_float_array("-analytical_expression 1.5 2.3 4.7")
3-element Vector{Float64}:
 1.5
 2.3
 4.7

julia> parse_float_array("-log_K 5.2 # comment")
1-element Vector{Float64}:
 5.2
ChemistryLab.parse_phases Method
julia
parse_phases(dat_content::AbstractString) -> Dict{String,Any}

Extract phase information from PHREEQC .dat file content.

Arguments

  • dat_content: full text content of a PHREEQC .dat file.

Returns

  • Dictionary mapping phase names to their properties (equation, log_K, analytical_expression, V⁰).

Parses the PHASES section and extracts reaction equations, equilibrium constants, analytical expressions, and molar volumes for each phase.

ChemistryLab.parse_reaction_stoich_cemdata Method
julia
parse_reaction_stoich_cemdata(reaction_line::AbstractString) -> (Vector, String, String)

Parse a reaction line from CEMDATA format and extract stoichiometric information.

Arguments

  • reaction_line: reaction string in CEMDATA format, optionally with a comment after '#'.

Returns

  • reactants: vector of dictionaries with "symbol" and "coefficient" keys.

  • modified_equation: equation string with added "@" markers for aqueous species.

  • comment: extracted comment string (empty if none).

The function automatically adds "@" suffixes to aqueous species without explicit charges (except for the first reactant).

ChemistryLab.merge_json Method
julia
merge_json(json_path::AbstractString, dat_path::AbstractString, output_path::AbstractString)

Merge PHREEQC .dat phase data into a ThermoFun JSON database file.

Arguments

  • json_path: path to input ThermoFun JSON file.

  • dat_path: path to PHREEQC .dat file containing phase definitions.

  • output_path: path for output merged JSON file.

Reads both files, extracts phases from the .dat file, merges them into the JSON database structure, and writes the result preserving the original JSON formatting.

ChemistryLab.merge_reactions Method
julia
merge_reactions(json_data::Dict, new_reactions::Dict) -> Dict

Merge new reactions from PHREEQC .dat into existing ThermoFun JSON data.

Arguments

  • json_data: existing ThermoFun database as a dictionary.

  • new_reactions: dictionary of new phase reactions to add.

Returns

  • Updated json_data with new reactions appended.

Only adds reactions that don't already exist (by symbol) and that have complete required fields (logKr, analytical_expression, equation).

ChemistryLab.write_reaction Method
julia
write_reaction(f::IO, reaction::Dict)

Write a single reaction dictionary to an IO stream in JSON format.

Arguments

  • f: output IO stream.

  • reaction: reaction dictionary with all required ThermoFun fields.

Helper function used by merge_json to write formatted JSON output.