Database Interoperability

So far, we have looked at the possibility of creating and manipulating any species, whether they exist or not. Creating an H₂O⁺⁴ molecule, for example, is not a problem.

HSO4 = Species("H₂O⁴⁺")
Species{Int64}
           name: H₂O⁴⁺
         symbol: H₂O⁴⁺
        formula: H₂O⁴⁺ ◆ H2O+4 ◆ HO⁴⁺
          atoms: H => 2, O => 1
         charge: 4
aggregate_state: AS_UNDEF
          class: SC_UNDEF
     properties: molar_mass = 18.015 g mol^-1

However, you will admit that it is a little strange...

Cemdata18 and PSI-Nagra-12-07 Databases

This is why Cement Chemistry relies on existing databases, in particular Cemdata18 and PSI-Nagra-12-07. Cemdata18 is a chemical thermodynamic database for hydrated Portland cements and alkali-activated materials. PSI-Nagra is a Chemical Thermodynamic Database. The formalism adopted for these databases is that of Thermofun which is a universal open-source client that delivers thermodynamic properties of substances and reactions at the temperature and pressure of interest. The information is stored in json files.

With ChemistryLab, you can parse a ThermoFun-like json file and return DataFrames for:

  • elements:
df_elements, df_substances, df_reactions = read_thermofun("../../../data/cemdata18-merged.json")
show(df_elements, allcols=true, allrows=true)
15×5 DataFrame
 Row  symbol  class    S                                  atomic_mass                        datasources         
      String  String   NamedTup…                          NamedTuple…                        Array…              
─────┼────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ Zz      CHARGE   (values = -65.34, units = missin…  (values = 0, units = missing, er…  ["PSI-Nagra-12-07"]
   2 │ H       ELEMENT  (values = 65.34, units = missing…  (values = 1.00795, units = missi…  ["PSI-Nagra-12-07"]
   3 │ C       ELEMENT  (values = 5.74, units = missing,…  (values = 12.0108, units = missi…  ["PSI-Nagra-12-07"]
   4 │ N       ELEMENT  (values = 95.8045, units = missi…  (values = 14.0067, units = missi…  ["PSI-Nagra-12-07"]
   5 │ O       ELEMENT  (values = 102.569, units = missi…  (values = 15.9994, units = missi…  ["PSI-Nagra-12-07"]
   6 │ Na      ELEMENT  (values = 51.3, units = missing,…  (values = 22.9898, units = missi…  ["PSI-Nagra-12-07"]
   7 │ Mg      ELEMENT  (values = 32.67, units = missing…  (values = 24.305, units = missin…  ["PSI-Nagra-12-07"]
   8 │ Al      ELEMENT  (values = 28.3, units = missing,…  (values = 26.9815, units = missi…  ["PSI-Nagra-12-07"]
   9 │ Si      ELEMENT  (values = 18.81, units = missing…  (values = 28.0855, units = missi…  ["PSI-Nagra-12-07"]
  10 │ S       ELEMENT  (values = 31.798, units = missin…  (values = 32.067, units = missin…  ["PSI-Nagra-12-07"]
  11 │ Cl      ELEMENT  (values = 111.54, units = missin…  (values = 35.453, units = missin…  ["PSI-Nagra-12-07"]
  12 │ K       ELEMENT  (values = 64.68, units = missing…  (values = 39.0983, units = missi…  ["PSI-Nagra-12-07"]
  13 │ Ca      ELEMENT  (values = 41.59, units = missing…  (values = 40.078, units = missin…  ["PSI-Nagra-12-07"]
  14 │ Fe      ELEMENT  (values = 27.28, units = missing…  (values = 55.845, units = missin…  ["PSI-Nagra-12-07"]
  15 │ Sr      ELEMENT  (values = 55.7, units = missing,…  (values = 87.62, units = missing…  ["PSI-Nagra-12-07"]

ChemistryLab.read_thermofun

  • species (aqueous, solid or gaseous phases):
show(df_substances, allcols=true, allrows=false)
228×17 DataFrame
 Row  species                            cemspecies                  name                               symbol    formula          charge  aggregate_state  class         Tst      Pst     TPMethods                          Cp                                 ΔfG                                ΔfH                                S                                  Vm                                 datasources                       
      Species                            CemSpecies?                 String                             String    String           Int64   String           String        Float64  Int64   Array…                             NamedTup…                          NamedTup…                          NamedTup…                          NamedTup…                          NamedTup…                          Array…?                           
─────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ H2O@ {H2O  l} [H2O@ ◆ H₂O@]        H2O@ {H2O  l} [H]           H2O  l                             H2O@      H2O@                  0  AS_AQUEOUS       SC_AQSOLVENT   298.15  100000  Dict{Any, Any}[Dict("method"=>"w…  (values = 75.3605, units = "J/(m…  (values = -237183, units = "J/mo…  (values = -285881, units = "J/mo…  (values = 69.923, units = "J/(mo…  (values = 1.80684, units = "J/ba…  ["SUPCRT:1992:prog:             …
   2 │ CaSiO3@ {CaSiO3  aq } [CaSiO3@ ◆…  CaSiO3@ {CaSiO3  aq } [CS]  CaSiO3  aq                         CaSiO3@   CaSiO3@               0  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 88.9034, units = "J/(m…  (values = -1.51756e6, units = "J…  (values = -1.66806e6, units = "J…  (values = -136.684, units = "J/(…  (values = 0, units = "J/bar", er…  ["AUG20_GEMS:2001:dat:         "…
   3 │ SiO3-2 {SiO3-2  aq } [SiO3-2 ◆ S…  missing                     SiO3-2  aq                         SiO3-2    SiO3-2               -2  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 119.826, units = "J/(m…  (values = -9.3851e5, units = "J/…  (values = -1.09874e6, units = "J…  (values = -80.2, units = "J/(mol…  (values = 0, units = "J/bar", er…  ["AUG20_GEMS:2001:dat:         "…
   4 │ SrSiO3@ {SrSiO3  aq (SiO3-2 + Sr…  missing                     SrSiO3  aq (SiO3-2 + Sr+2 = SrSi…  SrSiO3@   SrSiO3@               0  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 78.3857, units = "J/(m…  (values = -1527290, units = "J/m…  (values = -1.61743e6, units = "J…  (values = 79.9175, units = "J/(m…  (values = 1.63737, units = "J/ba…  ["Felmy_ea:2003:pap:         ", …
   5 │ HCN@ {HCN aq.            } [HC|-…  missing                     HCN aq.                            HCN@      HC|-1|N|0|@           0  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("method"=>"s…  (values = 0, units = "J/(mol*K)"…  (values = 114370, units = "J/mol…  (values = 103750, units = "J/mol…  (values = 131.3, units = "J/(mol…  (values = 0, units = "J/bar", er…  ["JULY_GEMS:2009:dat:"]
   6 │ SCN- {SCN-   (S0 = 144.348 from …  missing                     SCN-   (S0 = 144.348 from slop07…  SCN-      S|0|C|0|N|-1|-       -1  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("method"=>"s…  (values = -39.6916, units = "J/(…  (values = 92700, units = "J/mol"…  (values = 76400, units = "J/mol"…  (values = 144.012, units = "J/(m…  (values = 3.53618, units = "J/ba…  ["JULY_GEMS:2009:dat:"]
   7 │ AlSiO5-3 {AlSiO5-3  aq } [AlSiO5…  missing                     AlSiO5-3  aq                       AlSiO5-3  AlSiO5-3             -3  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 70.784, units = "J/(mo…  (values = -1.76901e6, units = "J…  (values = -2.02733e6, units = "J…  (values = -110.409, units = "J/(…  (values = -3.41317, units = "J/b…  ["JULY_GEMS:2009:dat:", ""]
   8 │ Si4O10-4 {Si4O10-4  aq } [Si4O10…  missing                     Si4O10-4  aq                       Si4O10-4  Si4O10-4             -4  AS_AQUEOUS       SC_AQSOLUTE    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 328.583, units = "J/(m…  (values = -3.60081e6, units = "J…  (values = -3.91598e6, units = "J…  (values = 305.198, units = "J/(m…  (values = 0, units = "J/bar", er…  ["JULY_GEMS:2009:dat:", "Lothenb…
  ⋮  │                 ⋮                              ⋮                               ⋮                     ⋮             ⋮           ⋮            ⋮              ⋮           ⋮       ⋮                     ⋮                                  ⋮                                  ⋮                                  ⋮                                  ⋮                                  ⋮                                  ⋮
 222 │ O2 {O2  g} [O|0|2 ◆ O₂]            missing                     O2  g                              O2        O|0|2                 0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 29.3222, units = "J/(m…  (values = 0, units = "J/mol", er…  (values = 0, units = "J/mol", er…  (values = 205.137, units = "J/(m…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:dat:          …
 223 │ N2 {N2  g} [N|0|2 ◆ N₂]            missing                     N2  g                              N2        N|0|2                 0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 29.1347, units = "J/(m…  (values = 0, units = "J/mol", er…  (values = 0, units = "J/mol", er…  (values = 191.61, units = "J/(mo…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:dat:          …
 224 │ CH4 {CH4  g} [C|-4|H4 ◆ CH₄]       missing                     CH4  g                             CH4       C|-4|H4               0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 35.7454, units = "J/(m…  (values = -50659, units = "J/mol…  (values = -74810, units = "J/mol…  (values = 186.263, units = "J/(m…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:dat:          …
 225 │ CO2 {CO2  g} [CO2 ◆ CO₂]           CO2 {CO2  g} [C̄]            CO2  g                             CO2       CO2                   0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 37.1485, units = "J/(m…  (values = -394393, units = "J/mo…  (values = -393509, units = "J/mo…  (values = 213.74, units = "J/(mo…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:dat:          …
 226 │ H2 {H2  g} [H|0|2 ◆ H₂]            missing                     H2  g                              H2        H|0|2                 0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 28.8177, units = "J/(m…  (values = 0, units = "J/mol", er…  (values = 0, units = "J/mol", er…  (values = 130.683, units = "J/(m…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:dat:          …
 227 │ H2S {H2S  g} [H2S|-2| ◆ H₂S]       missing                     H2S  g                             H2S       H2S|-2|               0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 34.2044, units = "J/(m…  (values = -33752, units = "J/mol…  (values = -20631.3, units = "J/m…  (values = 205.79, units = "J/(mo…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:dat:          …
 228 │ H2O {STEAM} [H2O ◆ H₂O]            H2O {STEAM} [H]             STEAM                              H2O       H2O                   0  AS_GAS           SC_GASFLUID    298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 40.072, units = "J/(mo…  (values = -228683, units = "J/mo…  (values = -242400, units = "J/mo…  (values = 187.25, units = "J/(mo…  (values = 2478.97, units = "J/ba…  ["Slop98_dat:1998:data:         …
                                                                                                                                                                                                                                                                                                                                                                                                                                213 rows omitted
  • reactions contained in the database
show(df_reactions, allcols=true, allrows=false)
148×14 DataFrame
 Row  symbol       equation                           reactants                          limitsTP                           Tst      Pst     TPMethods                          logKr                              ΔrCp                               ΔrG                                ΔrH                                ΔrS                                ΔrV                                datasources   
      String       String                             Dict…                              NamedTup…                          Float64  Int64   Array…                             NamedTup…                          NamedTup…                          NamedTup…                          NamedTup…                          NamedTup…                          NamedTup…                          Array…        
─────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ zeoliteP_Ca  zeoliteP_Ca = 2AlO2- + Ca+2 + 2S…  Dict{String, Real}("AlO2-"=>2, "…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -20.3, units = missing…  (values = -454.263, units = "-45…  (values = 1.15873e5, units = "J/…  (values = -32865.7, units = "J/m…  (values = -498.873, units = "J/(…  (values = -3.892, units = "J/bar…  ["Cemdata18"]
   2 │ M15SH        M15SH = 1.5Mg+2 + SiO2@ + 3OH- +…  Dict{String, Real}("M15SH"=>-1, …  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -23.57, units = missin…  (values = -571.681, units = "-57…  (values = 1.32282e5, units = "J/…  (values = 31561.9, units = "J/mo…  (values = -343.58, units = "J/(m…  (values = -8.73324, units = "J/b…  ["Cemdata18"]
   3 │ M075SH       M075SH = 1.5Mg+2 + 2SiO2@ + 3OH-…  Dict{String, Real}("SiO2@"=>2, "…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -28.8, units = missing…  (values = -595.047, units = "-59…  (values = 1.61635e5, units = "J/…  (values = 57008.6, units = "J/mo…  (values = -356.903, units = "J/(…  (values = -9.18341, units = "J/b…  ["Cemdata18"]
   4 │ chabazite    chabazite = 2AlO2- + Ca+2 + 4SiO…  Dict("AlO2-"=>2, "SiO2@"=>4, "ch…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -25.8, units = missing…  (values = -116.141, units = "-11…  (values = 1.47267e5, units = "J/…  (values = 1.13509e5, units = "J/…  (values = -113.225, units = "J/(…  (values = -7.8, units = "J/bar",…  ["Cemdata18"]
   5 │ zeoliteX     zeoliteX = 2AlO2- + 2Na+ + 2.5Si…  Dict{String, Real}("AlO2-"=>2, "…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -20.1, units = missing…  (values = -29.473, units = "-29.…  (values = 1.14732e5, units = "J/…  (values = 1.22773e5, units = "J/…  (values = 26.971, units = "J/(mo…  (values = -4.4899, units = "J/ba…  ["Cemdata18"]
   6 │ zeoliteY     zeoliteY = 2AlO2- + 2Na+ + 4SiO2…  Dict("AlO2-"=>2, "SiO2@"=>4, "H2…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -25, units = missing, …  (values = 20.321, units = "20.32…  (values = 142701.0, units = "J/m…  (values = 1.56608e5, units = "J/…  (values = 46.643, units = "J/(mo…  (values = -5.7611, units = "J/ba…  ["Cemdata18"]
   7 │ natrolite    natrolite = 2AlO2- + 2Na+ + 3SiO…  Dict("AlO2-"=>2, "natrolite"=>-1…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = -30.2, units = missing…  (values = -96.96, units = "-96.9…  (values = 1.72383e5, units = "J/…  (values = 1.60615e5, units = "J/…  (values = -39.47, units = "J/(mo…  (values = -6.8355, units = "J/ba…  ["Cemdata18"]
   8 │ Na2O         Na2O + 2H+ = 2Na+ + H2O@           Dict("H+"=>-2, "H2O@"=>1, "Na+"=…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 67.4268, units = missi…  (values = missing, units = missi…  (values = 3.84873e5, units = "J/…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
  ⋮  │      ⋮                       ⋮                                  ⋮                                  ⋮                     ⋮       ⋮                     ⋮                                  ⋮                                  ⋮                                  ⋮                                  ⋮                                  ⋮                                  ⋮                        ⋮
 142 │ O2(g)        O2 + 4e- + 4H+ = 2H2O@             Dict("H+"=>-4, "H2O@"=>2, "e-"=>…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 83.1049, units = missi…  (values = missing, units = missi…  (values = 4.74363e5, units = "J/…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
 143 │ C2AClH5      Ca2AlCl(OH)6(H2O)2 + 2H+ = 2Ca+2…  Dict("AlO2-"=>1, "H+"=>-2, "Ca+2…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 14.3652, units = missi…  (values = missing, units = missi…  (values = 81996.5, units = "J/mo…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
 144 │ K2O          K2O + 2H+ = H2O@ + 2K+             Dict("H+"=>-2, "K2O"=>-1, "H2O@"…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 84.0402, units = missi…  (values = missing, units = missi…  (values = 4.79702e5, units = "J/…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
 145 │ Brc          Mg(OH)2 + 2H+ = Mg+2 + 2H2O@       Dict("H+"=>-2, "Mg(OH)2"=>-1, "H…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 16.8401, units = missi…  (values = missing, units = missi…  (values = 96123.5, units = "J/mo…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
 146 │ CSHQ-JenH    (CaO)1.3333(SiO2)1(H2O)2.1667 + …  Dict{String, Real}("H+"=>-2.6666…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 22.1793, units = missi…  (values = missing, units = missi…  (values = 1.266e5, units = "J/mo…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
 147 │ H2O(g)       H2O = H2O@                         Dict("H2O@"=>1, "H2O"=>-1)         (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 1.48913, units = missi…  (values = missing, units = missi…  (values = 8499.95, units = "J/mo…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
 148 │ ettringite9  Ca6Al2(SO4)3(OH)12(H2O)3 + 4H+ =…  Dict("AlO2-"=>2, "H+"=>-4, "Ca+2…  (lowerT = 273.15, upperT = 298.1…   298.15  100000  Dict{Any, Any}[Dict("limitsTP"=>…  (values = 47.9412, units = missi…  (values = missing, units = missi…  (values = 2.73649e5, units = "J/…  (values = missing, units = missi…  (values = missing, units = missi…  (values = missing, units = missi…  ["Cemdata18"]
                                                                                                                                                                                                                                                                                                                                                                                                 133 rows omitted

Primary species extraction

It is also possible to retrieve primary species from the Cemdata18 database, primary species being the designation of a subset of species for which any species can be represented as the linear combination of primary species.

df_primaries = extract_primary_species("../../../data/CEMDATA18-31-03-2022-phaseVol.dat")
show(df_primaries, allcols=true, allrows=true)
15×7 DataFrame
 Row  species    symbol  gamma          formula  aggregate_state  atoms                       charge 
      SubStrin…  String  Array…         String   String           OrderedD…                   Int64  
─────┼────────────────────────────────────────────────────────────────────────────────────────────────
   1 │ AlO2-      AlO2-   [4.0, 0.064]   AlO2-    AS_AQUEOUS       OrderedDict(:Al=>1, :O=>2)      -1
   2 │ Ca+2       Ca+2    [4.86, 0.15]   Ca+2     AS_AQUEOUS       OrderedDict(:Ca=>1)              2
   3 │ Cl-        Cl-     [3.71, 0.01]   Cl-      AS_AQUEOUS       OrderedDict(:Cl=>1)             -1
   4 │ CO3-2      CO3-2   [5.4, 0.064]   CO3-2    AS_AQUEOUS       OrderedDict(:C=>1, :O=>3)       -2
   5 │ FeO2-      FeO2-   [4.0, 0.064]   FeO2-    AS_AQUEOUS       OrderedDict(:Fe=>1, :O=>2)      -1
   6 │ H2O        H2O@    [0.0, 0.0]     H2O@     AS_AQUEOUS       OrderedDict(:H=>2, :O=>1)        0
   7 │ H+         H+      [9.0, 0.064]   H+       AS_AQUEOUS       OrderedDict(:H=>1)               1
   8 │ K+         K+      [3.71, 0.01]   K+       AS_AQUEOUS       OrderedDict(:K=>1)               1
   9 │ Mg+2       Mg+2    [5.46, 0.22]   Mg+2     AS_AQUEOUS       OrderedDict(:Mg=>1)              2
  10 │ Na+        Na+     [4.32, 0.06]   Na+      AS_AQUEOUS       OrderedDict(:Na=>1)              1
  11 │ NO3-       NO3-    [3.0, 0.0]     NO3-     AS_AQUEOUS       OrderedDict(:N=>1, :O=>3)       -1
  12 │ SiO2       SiO2@   [0.0, 0.0]     SiO2@    AS_AQUEOUS       OrderedDict(:Si=>1, :O=>2)       0
  13 │ SO4-2      SO4-2   [5.31, -0.07]  SO4-2    AS_AQUEOUS       OrderedDict(:S=>1, :O=>4)       -2
  14 │ Sr+2       Sr+2    [5.48, 0.11]   Sr+2     AS_AQUEOUS       OrderedDict(:Sr=>1)              2
  15 │ Zz         Zz      [9.0, 0.064]   Zz       AS_AQUEOUS       OrderedDict(:Zz=>1)              1

ChemistryLab.extract_primary_species